﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Apewer.Web
{

    /// <summary>API 行为的参数。</summary>
    public sealed class ApiParameter : IToJson
    {

        ParameterInfo _parameter = null;
        bool _body = false;
        bool _query = false;

        /// <summary></summary>
        public ParameterInfo ParameterInfo { get => _parameter; }

        /// <summary></summary>
        public string Name { get => _parameter.Name; }

        /// <summary></summary>
        public Type Type { get => _parameter.ParameterType; }

        /// <summary></summary>
        public bool FromBody { get => _body; }

        /// <summary></summary>
        public bool FromQuery { get => _query; }

        /// <summary></summary>
        public override string ToString() => _parameter.Name;

        /// <summary></summary>
        public Json ToJson()
        {
            var format = ApiActionJsonFormat.Default ?? new ApiActionJsonFormat();
            var withReflection = format.WithReflection;
            return ToJson(withReflection);
        }

        /// <summary></summary>
        public Json ToJson(bool withReflection)
        {
            var json = Json.NewObject();
            json.SetProperty("name", _parameter.Name);
            if (withReflection)
            {
                json.SetProperty("type", _parameter.ParameterType.Name);
            }
            if (_body) json.SetProperty("fromBody", _body);
            if (_query) json.SetProperty("fromQuery", _query);
            return json;
        }

        /// <summary></summary>
        /// <exception cref="ArgumentNullException" />
        ApiParameter(ParameterInfo parameterInfo)
        {
            _parameter = parameterInfo ?? throw new ArgumentNullException(nameof(parameterInfo));
            _query = RuntimeUtility.Contains<FromQueryAttribute>(parameterInfo);
            _body = RuntimeUtility.Contains<FromBodyAttribute>(parameterInfo);
        }

        /// <summary></summary>
        public static ApiParameter Parse(ParameterInfo parameter)
        {
            if (parameter == null) return null;
            if (parameter.IsOut) return null;
            if (parameter.IsRetval) return null;
            return new ApiParameter(parameter);
        }

    }

}
